#include "StompedReality/Components/RenderInfoComponent.h"
#include "StompedReality/Core/Game.h"
#include "StompedReality/Core/Memory/ObjectPool.h"
#include "StompedReality/Core/Memory/ObjectPoolManager.h"
#include "StompedReality/Core/MessageSystem/Message.h"
#include "StompedReality/Core/MessageSystem/MessageTypes.h"
#include "StompedReality/Core/TypeSystem/TypeSystem.h"
#include <UnitTest++.h>
using namespace StompedReality::components;
static const StompedReality::ID NEW_OBJECT_ID_ADD = 0x10000;
SUITE ( Render_Info_Component_Test )
{
  TEST ( Test_Type )
  {
    //		std::cout << "L: " << offsetof(RenderInfoComponent, _layer) << std::endl;
    //	std::cout << "D: " << offsetof(RenderInfoComponent, RenderInfoComponent::_renderTranslationData.depth) << std::endl;
    //	std::cout << "tr: " << offsetof(RenderInfoComponent, RenderInfoComponent::_renderTranslationData.translation) << std::endl;
    //	std::cout << "rot: " << offsetof(RenderInfoComponent, RenderInfoComponent::_renderTranslationData.rotation) << std::endl;
    StompedReality::TYPE_ID riTypeID =
      StompedReality::type_system::TypeSystem::GetTypeID<RenderInfoComponent>( );
    StompedReality::type_system::TypeInfo* ricType =
      StompedReality::type_system::TypeSystem::GetType< RenderInfoComponent >( );
    RenderInfoComponent cmp;
    StompedReality::Game g;
    cmp.SetGame( &g );
    cmp.OnCreation( );

//		std::cout << ricType->to_s() << std::endl;
    Json::Value root;
    ricType->write ( root, ( char* ) &cmp );

//		std::cout << ricType->fields[0].offset << std::endl;
//CHECK_EQUAL(offsetof(RenderInfoComponent, RenderInfoComponent::_layer), ricType->fields[0].offset);
//CHECK_EQUAL(offsetof(RenderInfoComponent, RenderInfoComponent::_renderTranslationData.translation), ricType->fields[2].offset);
//CHECK_EQUAL(offsetof(RenderInfoComponent, RenderInfoComponent::_renderTranslationData.depth), ricType->fields[3].offset);
//CHECK_EQUAL(offsetof(RenderInfoComponent, RenderInfoComponent::_renderTranslationData.rotation), ricType->fields[4].offset);
//	std::cout << root;
  }
  TEST ( Create_Test_A )
  {
    StompedReality::TYPE_ID riTypeID =
      StompedReality::type_system::TypeSystem::GetTypeID<RenderInfoComponent>( );
    StompedReality::type_system::TypeInfo* ricType =
      StompedReality::type_system::TypeSystem::GetType<RenderInfoComponent>( );
    StompedReality::Game g;
    StompedReality::Core::ComponentObjectPool cmps;
    cmps.SetGame( &g );

    cmps.AddObjectPool ( riTypeID,
                         ( StompedReality::Core::MemoryBlock<StompedReality::Core::Component>* )
                         StompedReality::Core::ObjectPool<RenderInfoComponent>::CreateObjectPool ( 5 ) );
    StompedReality::ID idA = cmps.CreateObject ( StompedReality::type_system::TypeSystem::GetTypeID<RenderInfoComponent>( ) );
    RenderInfoComponent* cmpA = ( RenderInfoComponent* ) cmps.GetObject (
        riTypeID,
        idA );
    CHECK_EQUAL ( 0, cmpA->GetTranslation( ).GetX( ) );
    CHECK_EQUAL ( 0, cmpA->GetTranslation( ).GetY( ) );
    CHECK_EQUAL ( 0, cmpA->GetRotation( ) );
    CHECK_EQUAL ( 0, ( int ) cmpA->GetLayer( ) );
    CHECK_EQUAL ( true, cmps.HasObject ( riTypeID,
                                         NEW_OBJECT_ID_ADD + 0 ) );
    CHECK_EQUAL ( false, cmps.HasObject ( riTypeID,
                                          NEW_OBJECT_ID_ADD + 1 ) );
    CHECK_EQUAL ( false, cmps.HasObject ( riTypeID,
                                          NEW_OBJECT_ID_ADD + 2 ) );
    RenderInfoComponent* glCmp = ( RenderInfoComponent* ) cmps.GetObject (
        riTypeID,
        cmps.CreateObject ( riTypeID ) );
    glCmp->SetRotation ( 10 );
    glCmp->SetTranslation ( StompedReality::Math::Vector2 ( 5, 12 ) );
    CHECK_EQUAL ( 5, glCmp->GetTranslation( ).GetX( ) );
    CHECK_EQUAL ( 12, glCmp->GetTranslation( ).GetY( ) );
    CHECK_EQUAL ( 10, glCmp->GetRotation( ) );
    RenderInfoComponent* glCmpCheck = ( RenderInfoComponent* ) cmps.GetObject (
        riTypeID, NEW_OBJECT_ID_ADD + 1 );
    CHECK_EQUAL ( true, cmps.HasObject ( riTypeID,
                                         NEW_OBJECT_ID_ADD + 0 ) );
    CHECK_EQUAL ( true, cmps.HasObject ( riTypeID,
                                         NEW_OBJECT_ID_ADD + 1 ) );
    CHECK_EQUAL ( false, cmps.HasObject ( riTypeID,
                                          NEW_OBJECT_ID_ADD + 2 ) );
    CHECK_EQUAL ( 5, glCmpCheck->GetTranslation( ).GetX( ) );
    CHECK_EQUAL ( 12, glCmpCheck->GetTranslation( ).GetY( ) );
  }
  TEST ( Init_Render_Info_RenderKey_Tests )
  {
    StompedReality::TYPE_ID riTypeID =
      StompedReality::type_system::TypeSystem::GetTypeID<RenderInfoComponent>( );
    StompedReality::type_system::TypeInfo* ricType =
      StompedReality::type_system::TypeSystem::GetType<RenderInfoComponent>( );
    StompedReality::Game g;
    StompedReality::Core::ComponentObjectPool cmps;
    cmps.SetGame( &g );
    cmps.AddObjectPool ( riTypeID,
                         ( StompedReality::Core::MemoryBlock<StompedReality::Core::Component>* )
                         new StompedReality::Core::ObjectPool<RenderInfoComponent> ( 3 ) );
    StompedReality::ID idA = cmps.CreateObject ( riTypeID );
    RenderInfoComponent* cmpA = ( RenderInfoComponent* ) cmps.GetObject ( riTypeID, idA );
    cmpA->SetLayer ( 2 );
    cmpA->SetDepth ( 0.5f );
  }
  TEST ( Init_Render_Info_Json_Tests )
  {
    StompedReality::TYPE_ID riTypeID =
      StompedReality::type_system::TypeSystem::GetTypeID<RenderInfoComponent>( );
    StompedReality::type_system::TypeInfo* ricType =
      StompedReality::type_system::TypeSystem::GetType<RenderInfoComponent>( );
    StompedReality::Core::ComponentObjectPool cmps;
    StompedReality::Game g;
    cmps.SetGame( &g );
    cmps.AddObjectPool ( riTypeID,
                         ( StompedReality::Core::MemoryBlock<StompedReality::Core::Component>* )
                         new StompedReality::Core::ObjectPool<RenderInfoComponent> ( 3 ) );

    StompedReality::ID idA = cmps.CreateObject ( riTypeID );
    RenderInfoComponent* cmpA = ( RenderInfoComponent* ) cmps.GetObject ( riTypeID, idA );
    cmpA->SetLayer ( 2 );
    cmpA->SetRotation ( 45 );
    cmpA->SetTranslation ( StompedReality::Math::Vector2 ( 32, 54 ) );
    cmpA->SetDepth ( 0.2f );
    CHECK_EQUAL ( 2, cmpA->GetLayer( ) );
    CHECK_CLOSE ( 0.2f, cmpA->GetDepth( ), 0.0001f );
    CHECK_CLOSE ( 45, cmpA->GetRotation( ), 0.0001f );
    CHECK_CLOSE ( 32, cmpA->GetTranslation( ).GetX( ), 0.0001f );
    CHECK_CLOSE ( 54, cmpA->GetTranslation( ).GetY( ), 0.0001f );
    Json::Value root;
    ricType->write ( root, ( char* ) cmpA );

    //std::cout << "RI node" << std::endl;
    //std::cout << root;
    StompedReality::ID idB = cmps.CreateObject ( riTypeID );
    RenderInfoComponent* cmpB = ( RenderInfoComponent* ) cmps.GetObject ( riTypeID, idB );
    ricType->read ( root, ( char* ) cmpB );
    CHECK_EQUAL ( cmpA->GetLayer( ), cmpB->GetLayer( ) );
    CHECK_EQUAL ( cmpA->GetDepth( ), cmpB->GetDepth( ) );
    CHECK_CLOSE ( cmpA->GetRotation( ), cmpB->GetRotation( ), 0.0001f );
    CHECK_CLOSE ( cmpA->GetTranslation( ).GetX( ), cmpB->GetTranslation( ).GetX( ), 0.0001f );
    CHECK_CLOSE ( cmpA->GetTranslation( ).GetY( ), cmpB->GetTranslation( ).GetY( ), 0.0001f );
  }
}